package com.xbongbong.crm.perform.query.list.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.crm.service.CommunicatePlanListService;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.constant.TimeConstant;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.ext.ConditionsEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.elasticsearch.pojo.XbbAggregatedPage;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.elasticsearch.util.EsUtil;
import com.xbongbong.paas.elasticsearch.util.XbbElasticsearchRestTemplate;
import com.xbongbong.paas.enums.ConditionEnum;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.enums.PlatFormEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.pojo.ButtonPojo;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.helper.PageHelper;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.paas.util.ItemUtil;
import com.xbongbong.parent.pojo.list.ButtonPermissionPojo;
import com.xbongbong.parent.pojo.list.CommunicatePlanAnalysisDataPojo;
import com.xbongbong.parent.pojo.list.CommunicatePlanAnalysisDataVO;
import com.xbongbong.parent.pojo.list.CommunicatePlanConditionPojo;
import com.xbongbong.parent.pojo.list.CommunicatePlanResultPojo;
import com.xbongbong.parent.pojo.list.FieldListPojo;
import com.xbongbong.pro.constant.ElasticConstant;
import com.xbongbong.pro.constant.RangeScreenConstant;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.ApprovalErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.CommuicatePlanErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.permission.enums.ProPermissionAliasEnum;
import com.xbongbong.pro.formexplain.pojo.HandleExplainPojo;
import com.xbongbong.pro.weblist.pojo.CustomerPlanPojo;
import com.xbongbong.pro.weblist.pojo.dto.CommunicatePlanDTO;
import com.xbongbong.pro.weblist.pojo.vo.CustomerPlanVO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.CommunicatePlanUserEntity;
import com.xbongbong.saas.enums.ListBatchEnum;
import com.xbongbong.saas.enums.ListGroupEnum;
import com.xbongbong.saas.enums.ListTopButtonEnum;
import com.xbongbong.saas.enums.SaasBatchEnum;
import com.xbongbong.saas.enums.SaasButtonEnum;
import com.xbongbong.saas.enums.SaasSubButtonEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.CommunicatePlanEnum;
import com.xbongbong.saas.enums.dictionary.CommunicatePlanStatusEnum;
import com.xbongbong.saas.model.CommunicatePlanUserModel;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.model.UserModel;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;

/**
 * @author sunshaoxiang
 * @ClassName CommunicatePlanServiceImpl
 * @Description 访客计划列表业务层
 * @Date 2022/5/27 16:20
 * @Version 1.0
 **/
@Service("communicatePlanListServiceImpl")
public class CommunicatePlanListServiceImpl implements CommunicatePlanListService {

    public static final Logger LOGGER = LoggerFactory.getLogger(CommunicatePlanListServiceImpl.class);

    private static final String TREE_TYPE_STAFF = "staff";
    private static final String TREE_TYPE_DEPARTMENT = "department";

    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private EsHelper esHelper;
    @Resource
    private UserModel userModel;
    @Resource
    private XbbElasticsearchRestTemplate xbbElasticsearchRestTemplate;
    @Resource
    private CommunicatePlanUserModel communicatePlanUserModel;


    @Override
    public CustomerPlanVO list(CommunicatePlanDTO communicatePlanDTO) throws XbbException {
        // 处理首页访客计划只包含我执行的
        if (Objects.equals(communicatePlanDTO.getFromIndex(),BasicConstant.ONE)){
            communicatePlanDTO.setListGroupId(ListGroupEnum.COMMUNICATE_PLAN_RESPONSIBLE.getCode());
        }
        FieldListPojo fieldListPojo = new FieldListPojo(communicatePlanDTO.getCorpid(), communicatePlanDTO.getFormId(),
                communicatePlanDTO.getSaasMark(), communicatePlanDTO.getBusinessType(), communicatePlanDTO.getLoginUser());

        //获取并处理表单解释
        HandleExplainPojo explainPojo = getExplain(fieldListPojo);
        //获取并处理表单数据
        CommunicatePlanAnalysisDataVO  communicatePlanAnalysisDataVO = getData(communicatePlanDTO, explainPojo);
        //处理权限按钮
        ButtonPermissionPojo buttonPermissionPojo = handlePermmisionButton(communicatePlanDTO.getLoginUser());
        CommunicatePlanResultPojo communicatePlanResultPojo = new CommunicatePlanResultPojo(communicatePlanDTO.getCorpid(), communicatePlanAnalysisDataVO.getPlanList(), communicatePlanAnalysisDataVO.getExplains(),
                communicatePlanAnalysisDataVO.getPlanIdList(), communicatePlanDTO.getPage(), communicatePlanDTO.getPageSize(), communicatePlanAnalysisDataVO.getTotalElements(), buttonPermissionPojo);
        //封装VO对象返回给前端
        return getResultVO(communicatePlanResultPojo);

    }



    @Override
    public HandleExplainPojo getExplain(FieldListPojo fieldListPojo) throws XbbException {
        HandleExplainPojo handleExplainPojo = new HandleExplainPojo();
        PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByBusinessType(XbbRefTypeEnum.COMMUNICATE_PLAN.getCode(),fieldListPojo.getCorpid());
        UserVO loginUser = fieldListPojo.getUserVO();
        if (Objects.isNull(paasFormExplainEntity)){
            LOGGER.error("communicatePlan list error:corpid:" + fieldListPojo.getCorpid() + ",user:" + loginUser.getName() + ",userId:" + loginUser.getId());
            throw new XbbException(ApprovalErrorCodeEnum.API_ERROR_209012);
        }
        List<FieldAttrEntity> explainList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
        handleExplainPojo.setExplainList(explainList);
        handleExplain();
        return handleExplainPojo;
    }

    @Override
    public CommunicatePlanAnalysisDataVO getData(CommunicatePlanDTO communicatePlanDTO, HandleExplainPojo explainPojo) throws XbbException {
        //前置条件处理
        CommunicatePlanConditionPojo communicatePlanConditionPojo = new CommunicatePlanConditionPojo(communicatePlanDTO.getCorpid(), communicatePlanDTO.getPlatform(), communicatePlanDTO.getRangeScreen(), communicatePlanDTO.getDate(),
                communicatePlanDTO.getNameLike(), communicatePlanDTO.getCustomerId(),communicatePlanDTO.getStatus(), communicatePlanDTO.getFromIndex(), communicatePlanDTO.getPid(), communicatePlanDTO.getTreeType(), communicatePlanDTO.getListGroupId(), communicatePlanDTO.getUserId());
        List<ConditionsEntityExt> conditionsEntityExts = handleCondition(communicatePlanConditionPojo);
        //Es查询数据
        XbbAggregatedPage<PaasFormDataEntityExt> dataByEs = getDataByEs(communicatePlanDTO.getCorpid(), communicatePlanDTO.getFieldList(), conditionsEntityExts, communicatePlanDTO.getPage(), communicatePlanDTO.getPageSize());
        //解析数据
        CommunicatePlanAnalysisDataVO communicatePlanAnalysisDataVO = analysisData(dataByEs.getContent(), explainPojo, communicatePlanDTO.getCorpid());
        communicatePlanAnalysisDataVO.setTotalElements(dataByEs.getTotalElements());
        return communicatePlanAnalysisDataVO;
    }

    /**
     * 解析数据，包括通用解析和特殊解析
     * @param paasFormDataEntityExts
     * @param explainPojo
     * @param corpid
     * @return
     */
    private CommunicatePlanAnalysisDataVO analysisData(List<PaasFormDataEntityExt> paasFormDataEntityExts, HandleExplainPojo explainPojo, String corpid) {
        CommunicatePlanAnalysisDataVO communicatePlanAnalysisDataVO = new CommunicatePlanAnalysisDataVO();
        List<CustomerPlanPojo> planList = new ArrayList<>();
        List<Long> planIdList = new ArrayList<>();

        //这里后面看能不能优化
        Set<String> creatorUserSet = new HashSet<>();
        for (PaasFormDataEntityExt entity : paasFormDataEntityExts){
            // 系统生成的不查询
            if (!Objects.equals(PaasConstant.SYS_USER_ID, entity.getCreatorId())) {
                creatorUserSet.add(entity.getCreatorId());
            }
        }
        Map<String,String> userNameMap = userModel.getUserNameMap(corpid,new ArrayList<>(creatorUserSet));
        CommunicatePlanAnalysisDataPojo communicatePlanAnalysisDataPojo = new CommunicatePlanAnalysisDataPojo(planList, explainPojo.getExplainList(), planIdList, userNameMap);
        paasFormDataEntityExts.forEach(paasFormDataEntityExt -> {
            analysisSingleData(paasFormDataEntityExt, communicatePlanAnalysisDataPojo);
        });
        communicatePlanAnalysisDataVO.setPlanList(planList);
        communicatePlanAnalysisDataVO.setPlanIdList(planIdList);
        communicatePlanAnalysisDataVO.setPaasFormDataEntityExts(paasFormDataEntityExts);
        return communicatePlanAnalysisDataVO;

    }

    /**
     * 解析单条数据，将方法抽取的原因是想尽可能的在一次循环中将所有数据解析动作做完，避免上下游多次循环操作
     * @param paasFormDataEntityExt
     * @param communicatePlanAnalysisDataPojo
     */
    private void analysisSingleData(PaasFormDataEntityExt paasFormDataEntityExt, CommunicatePlanAnalysisDataPojo communicatePlanAnalysisDataPojo) {
        //通用解析
        commonAnalysisSingleData(paasFormDataEntityExt, communicatePlanAnalysisDataPojo);
        //特殊解析
        specialAnalysisSingleData(paasFormDataEntityExt, communicatePlanAnalysisDataPojo);

    }

    /**
     * 特殊数据解析
     * @param paasFormDataEntityExt
     * @param communicatePlanAnalysisDataPojo
     */
    private void specialAnalysisSingleData(PaasFormDataEntityExt paasFormDataEntityExt, CommunicatePlanAnalysisDataPojo communicatePlanAnalysisDataPojo) {
    }

    /**
     * 通用数据解析
     * @param paasFormDataEntityExt
     * @param communicatePlanAnalysisDataPojo
     */
    private void commonAnalysisSingleData(PaasFormDataEntityExt paasFormDataEntityExt, CommunicatePlanAnalysisDataPojo communicatePlanAnalysisDataPojo) {
        CustomerPlanPojo customerPlanPojo = new CustomerPlanPojo();
        JSONObject data = paasFormDataEntityExt.getData();
        List<FieldAttrEntity> explains = communicatePlanAnalysisDataPojo.getExplains();
        Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(JSONArray.toJSONString(explains));
        List<CustomerPlanPojo> planList = communicatePlanAnalysisDataPojo.getPlanList();
        List<Long> planIdList = communicatePlanAnalysisDataPojo.getPlanIdList();
        Map<String, String> userNameMap = communicatePlanAnalysisDataPojo.getUserNameMap();
        try {
            planIdList.add(paasFormDataEntityExt.getDataId());
            customerPlanPojo.setId(paasFormDataEntityExt.getDataId());
            customerPlanPojo.setCustomerId(data.getLong(CommunicatePlanEnum.LINK_CUSTOMER.getAttr()));
            customerPlanPojo.setCustomerName(data.getString(CommunicatePlanEnum.CUSTOMER_NAME_LINK_TEXT.getAttr()));
            // 简单客户数据，方便访客计划列表页跳客户详情
            JSONObject linkCustomer = new JSONObject();
            linkCustomer.put(StringConstant.DATA_ID, data.getLong(CommunicatePlanEnum.LINK_CUSTOMER.getAttr()));
            linkCustomer.put("saasMark", SaasMarkEnum.SAAS.getCode());
            linkCustomer.put(StringConstant.BUSINESS_TYPE, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode());
            customerPlanPojo.setLinkCustomer(linkCustomer);
            customerPlanPojo.setName(data.getString(CommunicatePlanEnum.NAME.getAttr()));
            Integer status = data.getInteger(CommunicatePlanEnum.STATUS.getAttr());
            status = status == null || status == 0 ? 1 : status;
            customerPlanPojo.setStatus(status);
            customerPlanPojo.setIsDelay(data.getInteger(CommunicatePlanEnum.IS_DELAY.getAttr()));
            customerPlanPojo.setMemo(data.getString(CommunicatePlanEnum.MEMO.getAttr()));
            customerPlanPojo.setCommunicateTime(data.getLong(CommunicatePlanEnum.COMMUNICATE_TIME.getAttr()));

            FieldAttrEntity fieldAttrEntity = explainMap.get(CommunicatePlanEnum.TARGET.getAttr());
            if (fieldAttrEntity == null) {
                return;
            }
            if (Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.COMBO.getType())) {
                customerPlanPojo.setVisitContent(ItemUtil.analysisComboReturnStr(data, fieldAttrEntity));
            }
            // 是否系统生成
            if (Objects.equals(PaasConstant.SYS_USER_ID, paasFormDataEntityExt.getCreatorId())) {
                customerPlanPojo.setUserId(paasFormDataEntityExt.getCreatorId());
                customerPlanPojo.setUserName(I18nMessageUtil.getMessage(PaasConstant.SYS_GENERATED));
            } else {
                customerPlanPojo.setUserId(paasFormDataEntityExt.getCreatorId());
                customerPlanPojo.setUserName(userNameMap.get(paasFormDataEntityExt.getCreatorId()));
            }
            // 方便前端跳转
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("dataId", paasFormDataEntityExt.getDataId());
            jsonObject.put("saasMark", SaasMarkEnum.SAAS.getCode());
            jsonObject.put("businessType", XbbRefTypeEnum.COMMUNICATE_PLAN.getCode());
            jsonObject.put("appId", paasFormDataEntityExt.getAppId());
            jsonObject.put("menuId", paasFormDataEntityExt.getMenuId());
            jsonObject.put("formId", paasFormDataEntityExt.getFormId());
            customerPlanPojo.setSimpleEntity(jsonObject);
            planList.add(customerPlanPojo);
        }catch (Exception e){
            LOGGER.error("CommunicatePlanListServiceImpl.commonAnalysisSingleData error:", e);
        }
    }

    /**
     * Es 中条件查询数据
     * @param corpid
     * @param fieldList
     * @param conditionsEntityExtList
     * @param page
     * @param size
     * @return
     * @throws XbbException
     */
    private XbbAggregatedPage<PaasFormDataEntityExt> getDataByEs(String corpid, List<String> fieldList, List<ConditionsEntityExt> conditionsEntityExtList, Integer page, Integer size) throws XbbException {
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        //解析查询条件
        EsUtil.parseCondition(boolQueryBuilder,conditionsEntityExtList,null, corpid, XbbRefTypeEnum.COMMUNICATE_PLAN.getCode());
        boolQueryBuilder.filter(termQuery("corpid.keyword",corpid ));
        boolQueryBuilder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
        sourceBuilder.sort(new FieldSortBuilder("data." +  CommunicatePlanEnum.COMMUNICATE_TIME.getAttr()).order(SortOrder.ASC));
        boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_COMMUNICATE_PLAN.getType()));
        sourceBuilder.query(boolQueryBuilder);
        EsUtil.setFieldList(sourceBuilder,fieldList);
        PageRequest pageRequest;
        try {
            pageRequest = EsUtil.setPage(sourceBuilder, page, size);
        }catch (Exception e){
            LOGGER.error("访客计划统计1",e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        SearchRequest searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_COMMUNICATE_PLAN.getIndex());
        searchRequest.source(sourceBuilder);
        XbbAggregatedPage<PaasFormDataEntityExt> esEntities = xbbElasticsearchRestTemplate.queryForPages(pageRequest,searchRequest, PaasFormDataEntityExt.class);
        if (esEntities == null) {
            LOGGER.error("访客计划统计2",JSONObject.toJSONString(searchRequest));
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return esEntities;

    }

    /**
     * 访客计划数据获取查询条件
     * @param communicatePlanConditionPojo
     * @return
     * @throws XbbException
     */
    private List<ConditionsEntityExt> handleCondition(CommunicatePlanConditionPojo communicatePlanConditionPojo) throws XbbException {
        List<ConditionsEntityExt> conditionsEntityExts = getCommonConditions(communicatePlanConditionPojo);
        conditionsEntityExts.addAll(getSpecialConditons(communicatePlanConditionPojo));
        return conditionsEntityExts;
    }

    /**
     * 特殊的查询条件获取
     * @param communicatePlanConditionPojo
     * @return
     * @throws XbbException
     */
    private List<ConditionsEntityExt> getSpecialConditons(CommunicatePlanConditionPojo communicatePlanConditionPojo) throws XbbException{
        List<ConditionsEntityExt> conditionsEntityExts = new ArrayList<>();
        //创建时间(区间)
        conditionsEntityExts.add(getDateCondition(communicatePlanConditionPojo.getDate()));
        //父子文档查询参数
        conditionsEntityExts.add(gateTeamCondition(communicatePlanConditionPojo));
        //返回类型
        if (Objects.equals(communicatePlanConditionPojo.getFromIndex(), BasicConstant.ONE)) {
            conditionsEntityExts.add(getTypeCondition());
        }
        return conditionsEntityExts;
    }

    /**
     * 父子文档查询参数
     * @param communicatePlanConditionPojo
     * @return
     * @throws XbbException
     */
    private ConditionsEntityExt gateTeamCondition(CommunicatePlanConditionPojo communicatePlanConditionPojo) throws XbbException {
        // 获取查询的员工
        List<String> userIdList = getUserIdList(communicatePlanConditionPojo);
        Set<String> userSet = new LinkedHashSet<>(userIdList);
        ConditionsEntityExt teamConditionsEntityExt = new ConditionsEntityExt(FieldTypeEnum.TEAM_USER.getAlias(), null, FieldTypeEnum.TEAM_USER.getType(), ConditionEnum.IN.getSymbol(), new ArrayList<>(userSet));
        return teamConditionsEntityExt;
    }

    /**
     * 获取返回类型条件
     * @return
     */
    private ConditionsEntityExt getTypeCondition() {
        ConditionsEntityExt typeCondition = new ConditionsEntityExt();
        typeCondition.setAttr(CommunicatePlanEnum.STATUS.getAttr());
        typeCondition.setFieldType(CommunicatePlanEnum.STATUS.getFieldType());
        typeCondition.setName(CommunicatePlanEnum.STATUS.getAttrName());
        typeCondition.setSymbol(ConditionEnum.IN.getSymbol());
        typeCondition.setValue(Arrays.asList(CommunicatePlanStatusEnum.NO_FOLLOW.getCode(),CommunicatePlanStatusEnum.DELAY.getCode()));
        return typeCondition;
    }

    /**
     * 获取创建时间（区间条件）
     * @param date
     * @return
     * @throws XbbException
     */
    private ConditionsEntityExt getDateCondition(String date) throws XbbException {
        //创建时间(区间)
        try {
            ConditionsEntityExt dateCondition = new ConditionsEntityExt();
            int  dateInt = StringUtil.isEmpty(date) ? DateUtil.getTodayInt() : DateUtil.getInt(date, new SimpleDateFormat("yyyy-MM-dd"));
            dateCondition.setAttr(CommunicatePlanEnum.COMMUNICATE_TIME.getAttr());
            dateCondition.setFieldType(CommunicatePlanEnum.COMMUNICATE_TIME.getFieldType());
            dateCondition.setName(CommunicatePlanEnum.COMMUNICATE_TIME.getAttrName());
            dateCondition.setSymbol(ConditionEnum.RANGE.getSymbol());
            dateCondition.setValue(Arrays.asList(dateInt,dateInt + TimeConstant.SECONDS_PER_DAY));
            return dateCondition;
        } catch (Exception e) {
            throw new XbbException(CommuicatePlanErrorCodeEnum.API_ERROR_214006);
        }
    }

    /**
     * 重构前 -> com.xbongbong.saas.service.impl.CommunicatePlanServiceImpl#setConditionList(com.xbongbong.pro.weblist.pojo.dto.CommunicatePlanDTO)
     * @param communicatePlanConditionPojo
     * @return
     */
    private List<ConditionsEntityExt> getCommonConditions(CommunicatePlanConditionPojo communicatePlanConditionPojo) throws XbbException {
        List<ConditionsEntityExt> conditionsEntityExtList = new ArrayList<>();
        rangeScreen(communicatePlanConditionPojo, conditionsEntityExtList);
        // 访客计划模糊查询，查的是客户名称或电话
        String nameLike = communicatePlanConditionPojo.getNameLike();
        List<Object> customerId = new ArrayList<>();
        if (nameLike != null && !StringUtil.isEmpty(nameLike, true)) {
            BoolQueryBuilder nameLikeQuery = boolQuery();
            nameLikeQuery.filter(termQuery("corpid.keyword", communicatePlanConditionPojo.getCorpid()));
            nameLikeQuery.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
            EsUtil.setNameLike(SaasMarkEnum.SAAS.getCode(), nameLike, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), false, nameLikeQuery,true,null, null);
            List<PaasFormDataEntityExt> customerList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_CUSTOMER,nameLikeQuery,PaasFormDataEntityExt.class, Collections.singletonList(FieldTypeEnum.DATAID.getAlias()));
            customerList.forEach(item ->{
                customerId.add(item.getDataId());
            });
            if (!customerId.isEmpty()) {
                conditionsEntityExtList.add(EsUtil.packageContions(CommunicatePlanEnum.LINK_CUSTOMER.getAttr(), customerId, ConditionEnum.IN, CommunicatePlanEnum.LINK_CUSTOMER.getFieldType()));
            } else {
                conditionsEntityExtList.add(EsUtil.packageContions(CommunicatePlanEnum.LINK_CUSTOMER.getAttr(), Collections.singletonList(-1L), ConditionEnum.EQUAL, CommunicatePlanEnum.LINK_CUSTOMER.getFieldType()));
            }
        }
        String customerId1 = communicatePlanConditionPojo.getCustomerId();
        //访客计划模糊查询优化--->精确匹配（有家公司数据量过大，导出报错）
        if (customerId1 != null && !StringUtil.isEmpty(customerId1, true)) {
            List<Object> customerIds = Arrays.asList(customerId1);
            conditionsEntityExtList.add(EsUtil.packageContions(CommunicatePlanEnum.LINK_CUSTOMER.getAttr(), customerIds, ConditionEnum.IN, CommunicatePlanEnum.LINK_CUSTOMER.getFieldType()));
        }
        //访客计划状态
        CommunicatePlanStatusEnum statusEnum = CommunicatePlanStatusEnum.getByCode(Objects.toString(communicatePlanConditionPojo.getStatus(),""));
        ConditionsEntityExt statusCondition = new ConditionsEntityExt();
        ConditionsEntityExt delayCondition = new ConditionsEntityExt();
        switch (statusEnum){
            case NO_FOLLOW:
                statusCondition.setAttr(CommunicatePlanEnum.STATUS.getAttr());
                statusCondition.setFieldType(CommunicatePlanEnum.STATUS.getFieldType());
                statusCondition.setName(CommunicatePlanEnum.STATUS.getAttrName());
                statusCondition.setSymbol(ConditionEnum.EQUAL.getSymbol());
                statusCondition.setValue(Collections.singletonList((statusEnum.getCode().toString())));
                delayCondition.setAttr(CommunicatePlanEnum.IS_DELAY.getAttr());
                delayCondition.setFieldType(CommunicatePlanEnum.IS_DELAY.getFieldType());
                delayCondition.setName(CommunicatePlanEnum.IS_DELAY.getAttrName());
                delayCondition.setSymbol(ConditionEnum.EQUAL.getSymbol());
                delayCondition.setValue(Collections.singletonList(0));
                conditionsEntityExtList.add(statusCondition);
                conditionsEntityExtList.add(delayCondition);
                break;
            case FINISH:
                statusCondition.setAttr(CommunicatePlanEnum.STATUS.getAttr());
                statusCondition.setFieldType(CommunicatePlanEnum.STATUS.getFieldType());
                statusCondition.setName(CommunicatePlanEnum.STATUS.getAttrName());
                statusCondition.setSymbol(ConditionEnum.EQUAL.getSymbol());
                statusCondition.setValue(Collections.singletonList((statusEnum.getCode().toString())));
                conditionsEntityExtList.add(statusCondition);
                break;
            case CANCEL:
                statusCondition.setAttr(CommunicatePlanEnum.STATUS.getAttr());
                statusCondition.setFieldType(CommunicatePlanEnum.STATUS.getFieldType());
                statusCondition.setName(CommunicatePlanEnum.STATUS.getAttrName());
                statusCondition.setSymbol(ConditionEnum.EQUAL.getSymbol());
                statusCondition.setValue(Collections.singletonList((statusEnum.getCode().toString())));
                conditionsEntityExtList.add(statusCondition);
                break;
            case DELAY:
                statusCondition.setAttr(CommunicatePlanEnum.STATUS.getAttr());
                statusCondition.setFieldType(CommunicatePlanEnum.STATUS.getFieldType());
                statusCondition.setName(CommunicatePlanEnum.STATUS.getAttrName());
                statusCondition.setSymbol(ConditionEnum.IN.getSymbol());
                statusCondition.setValue(Arrays.asList(CommunicatePlanStatusEnum.NO_FOLLOW.getCode().toString(),CommunicatePlanStatusEnum.DELAY.getCode().toString()));
                delayCondition.setAttr(CommunicatePlanEnum.IS_DELAY.getAttr());
                delayCondition.setFieldType(CommunicatePlanEnum.IS_DELAY.getFieldType());
                delayCondition.setName(CommunicatePlanEnum.IS_DELAY.getAttrName());
                delayCondition.setSymbol(ConditionEnum.EQUAL.getSymbol());
                delayCondition.setValue(Collections.singletonList(1));
                conditionsEntityExtList.add(statusCondition);
                conditionsEntityExtList.add(delayCondition);
                break;
            default:
                break;
        }
        return conditionsEntityExtList;
    }

    /**
     *
     * @param communicatePlanConditionPojo
     * @param conditionsEntityExtList
     * @throws XbbException
     */
    private void rangeScreen(CommunicatePlanConditionPojo communicatePlanConditionPojo, List<ConditionsEntityExt> conditionsEntityExtList) throws XbbException {
        if (Objects.equals(communicatePlanConditionPojo.getPlatform(), PlatFormEnum.DINGTALK.getValue())) {
            return;
        }
        JSONObject rangeScreen = communicatePlanConditionPojo.getRangeScreen();
        if (Objects.isNull(rangeScreen) || Objects.isNull(rangeScreen.get(RangeScreenConstant.TYPE)) || StringUtil.isEmpty(rangeScreen.getString(RangeScreenConstant.TYPE)) || Objects.isNull(rangeScreen.get(RangeScreenConstant.VALUE))) {
            return;
        }
        String type;
        List<String> values;
        try {
            type = rangeScreen.getString(RangeScreenConstant.TYPE);
            values = rangeScreen.getJSONArray(RangeScreenConstant.VALUE).toJavaList(String.class);
        } catch (Exception e) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001.getCode(), "customerCommunicateServiceimpl.rangeScreen中的commonFilter参数错误");
        }
        if (CollectionsUtil.isEmpty(values)) {
            return;
        }
        if (Objects.equals(type, RangeScreenConstant.DEPARTMENT)) {
            List<Long> deptIds = new ArrayList<>(values.size());
            values.forEach(item -> deptIds.add(Long.valueOf(item)));
            values = userModel.getUserIdsRecursionDep(deptIds, communicatePlanConditionPojo.getCorpid(), 1, true);
        }
        ConditionsEntityExt teamConditionsEntityExt = new ConditionsEntityExt(FieldTypeEnum.TEAM_USER.getAlias(), null, FieldTypeEnum.TEAM_USER.getType(), ConditionEnum.IN.getSymbol(), new ArrayList<>(values));
        conditionsEntityExtList.add(teamConditionsEntityExt);
    }

    /**
     * 处理表单解释（包括通用解析和特殊解析）
     */
    private void handleExplain() {

    }

    /**
     * 封装返回给前端的VO对象
     * @param communicatePlanResultPojo
     * @return
     */
    private CustomerPlanVO getResultVO(CommunicatePlanResultPojo communicatePlanResultPojo) {
        String corpid = communicatePlanResultPojo.getCorpid();
        List<Long> planIdList = communicatePlanResultPojo.getPlanIdList();
        List<CustomerPlanPojo> planList = communicatePlanResultPojo.getPlanList();
        Map<String,Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Integer page = communicatePlanResultPojo.getPage();
        Integer pageSize = communicatePlanResultPojo.getPageSize();
        long totalElements = communicatePlanResultPojo.getTotalElements();
        ButtonPermissionPojo buttonPermissionPojo = communicatePlanResultPojo.getButtonPermissionPojo();

        map.put("corpid",corpid);
        map.put("planIdIn",planIdList);
        map.put("del",0);
        List<CommunicatePlanUserEntity> communicatePlanUserEntityList = planList.isEmpty() ? new ArrayList<>() : communicatePlanUserModel.findEntitys(map);
        Map<String,List<CommunicatePlanUserEntity>> userMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (CommunicatePlanUserEntity entity : communicatePlanUserEntityList){
            List<CommunicatePlanUserEntity> entityList = userMap.getOrDefault(entity.getDataId().toString(),new ArrayList<>());
            entityList.add(entity);
            userMap.put(entity.getDataId().toString(),entityList);
        }
        CustomerPlanVO customerPlanVO = new CustomerPlanVO();
        customerPlanVO.setPlanList(planList);
        customerPlanVO.setUserMap(userMap);
        PageHelper pageHelper = new PageHelper(page, pageSize);
        pageHelper.setRowsCount((int) totalElements);
        customerPlanVO.setPageHelper(pageHelper);
        customerPlanVO.setBottomPermissions(buttonPermissionPojo.getBottomPermissions());
        customerPlanVO.setTopPermissions(buttonPermissionPojo.getTopPermissions());
        return customerPlanVO;
    }

    /**
     * 处理权限按钮
     * @param loginUser
     * @return
     */
    private ButtonPermissionPojo handlePermmisionButton(UserVO loginUser) {
        ButtonPermissionPojo buttonPermissionPojo = new ButtonPermissionPojo();
        //获取上部权限按钮
        buttonPermissionPojo.setTopPermissions(getTopPermmision(loginUser));
        //获取底部权限按钮
        buttonPermissionPojo.setBottomPermissions(getBottomPermmision());
        return buttonPermissionPojo;
    }

    /**
     * 获取上部权限按钮
     * @param loginUser
     * @return
     */
    private List<ButtonPojo> getTopPermmision(UserVO loginUser) {
        List<ListTopButtonEnum> topButtonEnumList = ListTopButtonEnum.getByBusinessType(XbbRefTypeEnum.COMMUNICATE_PLAN.getCode());
        List<ButtonPojo> topButtonList = new ArrayList<>();
        for (ListTopButtonEnum topButtonEnum : topButtonEnumList){
            if (Objects.equals(topButtonEnum, ListTopButtonEnum.COMMUNICATE_PLAN_ADD) && !loginUser.getPermSet().contains(ProPermissionAliasEnum.COMMUNICATE_PLAN_ADD.getAlias())) {
                continue;
            } else if (Objects.equals(topButtonEnum, ListTopButtonEnum.COMMUNICATE_PLAN_EXPORT) && !loginUser.getPermSet().contains(ProPermissionAliasEnum.COMMUNICATE_PLAN_EXPORT.getAlias())) {
                continue;
            }
            ButtonPojo buttonPojo = new ButtonPojo();
            BeanUtil.copyProperties(topButtonEnum.getAnEnum(),buttonPojo);
            if (Objects.equals(topButtonEnum.getAnEnum().getAttr(), SaasButtonEnum.EXPORT.getAttr())) {
                List<SaasSubButtonEnum> saasSubButtonEnumList = SaasSubButtonEnum.getByPermissionAlias(topButtonEnum.getBusinessType(),topButtonEnum,loginUser.getPermSet());
                List<ButtonPojo> subButtonList = new ArrayList<ButtonPojo>(){{
                    add(new ButtonPojo(){{BeanUtil.copyProperties(topButtonEnum.getAnEnum(), this);}});
                }};
                saasSubButtonEnumList.forEach(item->{
                    subButtonList.add(new ButtonPojo(){{setAttr(item.getAlias());setValue(item.getName());}});
                });
                buttonPojo.setSubButtons(subButtonList);
            }
            topButtonList.add(buttonPojo);
        }
        return topButtonList;
    }

    /**
     * 获取底部权限按钮
     * @return
     */
    private List<ButtonPojo>  getBottomPermmision() {
        List<ListBatchEnum> listBatchEnumList = ListBatchEnum.getByBusinessType(XbbRefTypeEnum.CUSTOMER.getCode());
        List<ButtonPojo> bottomButtonList = new ArrayList<>();
        //在访客计划这里获取客户跟进提醒的按钮权限
        for (ListBatchEnum batchEnum : listBatchEnumList){
            if (Objects.equals(batchEnum.getAnEnum().getAttr(), SaasBatchEnum.COMMUNICATE_NOTIFY.getAttr())){
                ButtonPojo buttonPojo = new ButtonPojo();
                BeanUtil.copyProperties(batchEnum.getAnEnum(),buttonPojo);
                buttonPojo.addBusinessType(XbbRefTypeEnum.PUSH_NOTIFY.getCode());
                buttonPojo.setDistributorMark(BasicConstant.ZERO);
                bottomButtonList.add(buttonPojo);
                break;
            }
        }
        return bottomButtonList;
    }

    /**
     * 获取查询的员工
     * 重构前 -> com.xbongbong.saas.service.impl.CommunicatePlanServiceImpl#getUserIdList(com.xbongbong.pro.weblist.pojo.dto.CommunicatePlanDTO)
     * @param communicatePlanConditionPojo 参数
     * @return 员工idList
     * @throws XbbException
     */
    private List<String> getUserIdList(CommunicatePlanConditionPojo communicatePlanConditionPojo) throws XbbException{
        String userId = communicatePlanConditionPojo.getUserId();
        String corpid = communicatePlanConditionPojo.getCorpid();
        UserEntity userEntity = userModel.getByKey(userId,corpid);
//        List<String> useridList;
        //可见的userId
        List<String> seenUserId = new ArrayList<>();
        //分组
        Integer listGroupId = communicatePlanConditionPojo.getListGroupId();
        listGroupId = listGroupId == null ? 0 : listGroupId;
        //TODO 丑陋
        switch (listGroupId) {
            case 0:
                //全部,不可以看到离职
                Integer dataPermission = userModel.getDataPermission(userEntity, SaasMarkEnum.SAAS, XbbRefTypeEnum.COMMUNICATE_PLAN.getCode(), null);
                seenUserId = userModel.getSubIdListByDataPermission(dataPermission, userEntity.getUserId(), userEntity.getCorpid(), BasicConstant.ZERO,false);
                break;
            case 21:
                //我的
                seenUserId.add(userId);
                break;
            case 22:
                //下属,不可以看到离职
                Integer permission = userModel.getDataPermission(userEntity, SaasMarkEnum.SAAS, XbbRefTypeEnum.COMMUNICATE_PLAN.getCode(), null);
                seenUserId = userModel.getSubIdListByDataPermission(permission, userEntity.getUserId(), userEntity.getCorpid(), BasicConstant.ZERO,true);
                break;
            default:
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        //选择的userId
        List<String> checkUserIdIn = new ArrayList<>();
        if(Objects.equals(communicatePlanConditionPojo.getTreeType(),TREE_TYPE_STAFF)){
            checkUserIdIn.add(communicatePlanConditionPojo.getPid());
            seenUserId.retainAll(checkUserIdIn);
        }else if(Objects.equals(communicatePlanConditionPojo.getTreeType(),TREE_TYPE_DEPARTMENT) && !Objects.equals(communicatePlanConditionPojo.getPid(),"1")){
            //如果是部门的情况下，要排除全公司的情况
            Long depId =StringUtil.StringToLong(communicatePlanConditionPojo.getPid());
            checkUserIdIn = userModel.getUserIdsRecursionDep(Collections.singletonList(depId),corpid);
            seenUserId.retainAll(checkUserIdIn);
        }else{
//            useridList=new ArrayList<>(seenUserId);
        }
        if(seenUserId.isEmpty()) {
            //TODO haibin.zhang 这边应该处理一下
            seenUserId.add("-1");
        }
        return seenUserId;
    }

}
